package com.hpe.wx.performance.mongo.statusrecord.service;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MalformedObjectNameException;
import javax.management.ReflectionException;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hpe.wx.performance.mongo.jmxObj.dao.JmxObjDao;
import com.hpe.wx.performance.mongo.jmxObj.domain.JmxObj;
import com.hpe.wx.performance.mongo.statusrecord.dao.StatusRecordDao;
import com.hpe.wx.performance.mongo.statusrecord.domain.StatusRecord;
import com.hpe.wx.performance.redis.utils.JMXUtils;

@Service
@Transactional
public class StatusRecordServiceImpl implements StatusRecordService {
	@Autowired
	private JmxObjDao dao_jmx;

	@Autowired
	private StatusRecordDao dao_sr;

	private static final Logger logger = Logger.getLogger(StatusRecordServiceImpl.class);

	@Override
	public void addARecord2DB(String jmxId) throws MalformedObjectNameException, AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException {
		JmxObj jmxObj = dao_jmx.findOne(jmxId);
		if (null != jmxObj) {
			String jmxUrl = jmxObj.getUrl();
			String printLog = "";
			Date now = new Date();
			Long currentTimeStamp = now.getTime();

			StatusRecord statusRecord = new StatusRecord();

			statusRecord.setJmxId(jmxId);
			statusRecord.setGenerateTime(now);
			statusRecord.setCreatedDate(now);
			statusRecord.setGenerateTimestamp(currentTimeStamp);
			statusRecord.setStatus(1);
			statusRecord.setCreatedBy(0L); 

			// System Datas cpu and memery
			DecimalFormat df = new DecimalFormat("0.00");
			Map<String, Number> sysInfo = JMXUtils.getOperatingSystemInfo(jmxUrl, null, null);

			Long totalPhysicalMemorySize = (Long) sysInfo.get("TOTALPHYSICALMEMORYSIZE")/1024/1024;
			Long freePhysicalMemorySize = (Long) sysInfo.get("FREEPHYSICALMEMORYSIZE")/1024/1024;

			statusRecord.setMemTotal(totalPhysicalMemorySize);
			statusRecord.setMemUsed(totalPhysicalMemorySize - freePhysicalMemorySize);

			Double systemCpuLoad = (Double) sysInfo.get("SYSTEMCPULOAD") * 100;

			statusRecord.setCpuUsage(systemCpuLoad);

			String cpuper = df.format(systemCpuLoad);
			String memper = df.format((1 - freePhysicalMemorySize * 1.0 / totalPhysicalMemorySize) * 100);

			// heap and jvm Datas
			Map<String, Number> heapInfo = JMXUtils.getHeapInfo(jmxUrl, null, null);

			// long init = (Long) heapInfo.get("init");
			// long max = (Long) heapInfo.get("max");
			Long committed = (Long) heapInfo.get("committed") / 1024 / 1024;
			Long used = (Long) heapInfo.get("used") / 1024 / 1024;

			statusRecord.setHeapTotal(committed);
			statusRecord.setHeapUsed(used);

			String jvmper = df.format(used * 1.0 / committed * 100);
			
			statusRecord.setCreatedBy(0l);

			StatusRecord sss = dao_sr.save(statusRecord);
			
			System.out.println("insert a record, and the id of it is: " + sss.getId());

			// cpu
			// zAddData("CPU:" + md5jmxUrl, currentTimeStamp, cpuper + ":" +
			// currentTimeStamp);
			printLog += (currentTimeStamp + "###############cpuUsed: " + cpuper);

			// mem
			// zAddData("MEM:" + md5jmxUrl, currentTimeStamp, memper + ":" +
			// currentTimeStamp);
			printLog += ("###############memPer: " + memper);

			// jvm
			// zAddData("JVM:" + md5jmxUrl, currentTimeStamp, "" + jvmper + ":"
			// + currentTimeStamp);
			printLog += ("###############jvmPer: " + jvmper);

			// heap used
			// zAddData("HEAPUSED:" + md5jmxUrl, currentTimeStamp, "" + used +
			// ":" + currentTimeStamp);
			printLog += ("###############used: " + used);

			// heap committed
			// zAddData("HEAPCOMMITTED:" + md5jmxUrl, currentTimeStamp, "" +
			// committed + ":" + currentTimeStamp);
			printLog += ("###############committed: " + committed);

			// timestamp
			// zAddData("TIMESTAMP:" + md5jmxUrl, currentTimeStamp,
			// currentTimeStamp + ":TIMESTAMP");
			printLog += ("###############TIMESTAMP: " + currentTimeStamp);

			logger.info(printLog);
		}
	}

	@Override
	public StatusRecord getLastRecord(String jmxId) {
		System.out.println("getLastRecord---->" + jmxId);
		StatusRecord res = dao_sr.findLastByOrderByGenerateTimestampAsc();
		return res;
	}

	@Override
	public List<StatusRecord> getAllRecord() {
		List<StatusRecord> res = dao_sr.findAll();
		return res;
	}

	@Override
	public List<StatusRecord> getRecordBetween(Long start, Long end) {
		List<StatusRecord> res = dao_sr.findByGenerateTimestampBetween(start, end);
		return res;
	}

	@Override
	public List<StatusRecord> getRecordAfter(Long start) {
		List<StatusRecord> res = dao_sr.findByGenerateTimestampBetween(start, (new Date()).getTime());
		return res;
	}
}
